﻿using FlyingHat.Common.Attributes;
using FlyingHat.Common.Helper;
using FlyingHat.Extensions.Redis;
using FlyingHat.Model.Models.Global;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;

namespace FlyingHat.Extensions.Filter
{
    /// <summary>
    /// 缓存过滤器  控制器/方法范围
    /// </summary>
    public class CacheFilter : IAsyncActionFilter, IAsyncResultFilter
    {
        private readonly IRedisHelper redisHelper;

        public CacheFilter(IRedisHelper redisHelper)
        {
            this.redisHelper = redisHelper;
        }

        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            var cache = context.ActionDescriptor.EndpointMetadata.FirstOrDefault(i => i.GetType() == typeof(CachingAttribute));
            if (cache is CachingAttribute cachingAttribute)
            {
                // 如果是AOP则跳过
                if (!cachingAttribute.IsAop)
                {
                    var cacheKey = cachingAttribute.Key;
                    if (string.IsNullOrWhiteSpace(cachingAttribute.Key))
                    {
                        cacheKey = CustomCacheKey(context.HttpContext.Request);
                    }
                    var value = redisHelper.Get<IReturnModel>(cacheKey);
                    if (value != null)
                    {
                        context.Result = new JsonResult(value);
                        return;
                    }
                }
            }
            await next();
        }
        protected static string CustomCacheKey(HttpRequest request)
        {
            // 暂且以这个条件作为key，当然如果要更加明确，则需要仅一步分解参数
            var key = $"{request.Scheme}{request.Host.Value}{request.Path}";
            key = EncryptHelper.Get32Md5(key);
            return key;
        }

        public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
        {
            var cache = context.ActionDescriptor.EndpointMetadata.FirstOrDefault(i => i.GetType() == typeof(CachingAttribute));
            if (cache is CachingAttribute cachingAttribute)
            {
                // 如果是AOP则跳过
                if (!cachingAttribute.IsAop)
                {
                    var cacheKey = cachingAttribute.Key;
                    if (string.IsNullOrWhiteSpace(cachingAttribute.Key))
                    {
                        cacheKey = CustomCacheKey(context.HttpContext.Request);
                    }
                    // 如果key存在则不需要再次存储
                    if (!redisHelper.Exists(cacheKey))
                    {
                        if (context.Result is JsonResult result)
                        {
                            if (result != null && result.Value != null)
                            {
                                if (result.Value is IReturnModel returnModel)
                                {
                                    if (cachingAttribute.AbsoluteExpiration > 0)
                                    {
                                        redisHelper.Set(cacheKey, returnModel, cachingAttribute.AbsoluteExpiration);
                                    }
                                    else
                                    {
                                        redisHelper.Set(cacheKey, returnModel);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            await next();
        }
    }
}
